package com.qf.om.servlet;

import com.qf.om.entity.Admin;
import com.qf.om.myutils.DataUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.UUID;

@WebServlet(urlPatterns = "/registerfile")
public class RegisterFileServlet extends HttpServlet {
    public static String uploaderPath = "A:\\ideadata\\";

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        如果表单是上传类型，则数据无法通过getParameter获取
//        使用第三方包解析

//        1.创建一个表单处理项的工厂对象
        DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
//        2.创建一个Servlet的上传处理对象
        ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
//        说明：如果是中文名称的文件那么需要设置文件上传的路径编码格式
        servletFileUpload.setHeaderEncoding(" utf-8 ");
        /*
          3、通过servletFileUpload 解析请求中的数据流
            姓名：<input name="name"/> -> FileItem对象
            年龄：<input name="age"/> -> FileItem对象
            文件：<input name="file" type="file"/> -> FileItem对象(非普通的表单项)
            爱好：<input type=“checkbox” name="likes"/>唱歌 <input type=“checkbox” name="likes"/>唱歌 -> FileItem对象
         */
        List<FileItem> fileItems = null;
        try {
            fileItems = servletFileUpload.parseRequest(req);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        Admin admin = new Admin();
        Class aClass = admin.getClass();
        if (fileItems != null) {
            //循环处理FileItem集合
            for (FileItem fileItem : fileItems) {
                //判断当前的fileItem是不是普通的表单项
                if (fileItem.isFormField()) {
                    //如果为普通表单
                    System.out.println("获得了一个表单项：" + fileItem.getFieldName() + "：" + fileItem.getString("utf-8"));
                    //处理特殊属性
                    if ("birthday".equals(fileItem.getFieldName())) {
                        admin.setBirthday(fileItem.getString("utf-8"));
                    } else if ("power".equals(fileItem.getFieldName())) {
                        admin.addPower(fileItem.getString("utf-8"));
                    } else {
                        //其他类型默认交给反射处理
                        //一堆key-value -> Admin对象的对应属性中 ->
                        //item.getFieldName()-username
                        //item.getFieldName()-password
                        try {
                            //getDeclaredField获得私有的成员变量
                            Field field = aClass.getDeclaredField(fileItem.getFieldName());
                            //授权，操作私有成员变量
                            field.setAccessible(true);
                            //指定是admin类
                            field.set(admin, fileItem.getString("utf-8"));
                        } catch (Exception e) {
//                            e.printStackTrace();
                        }
                    }
                } else {
                    //获取文件的名称包含后缀
                    System.out.println("上传的文件名称：" + fileItem.getName());
                    String filename = UUID.randomUUID().toString();
                    //  new String(filename.getBytes("GBK"), "utf-8");
                    //  byte[] buffer = filename.getBytes("GBK"); 用gbk的方式解码成byte数组
                    //  new String(buffer, "utf-8"); 用utf-8的方式编码成字符串

                    try (
                            //说明当前是一个file表单项，获取该文件的上传输入流
                            //in 代表的就是客户端上传的文件
                            InputStream in = fileItem.getInputStream();
                            //准备自己的输出流 - "A:\\ideadata"
                            //输出流必须指定到文件，不能指定到文件夹！！！！！
                            //输出流中的路径必须存在，不会自动创建
                            OutputStream os = new FileOutputStream((uploaderPath + filename));
                    ) {
                        //设置每次传输的容量为10kb
//                        byte[] bytes = new byte[1024 * 10];
//                        int len;
//                        while ((len = in.read(bytes)) != -1) {
//                            os.write(bytes, 0, len);
//                        }
                        //使用工具类 实现文件的拷贝
                        IOUtils.copy(in, os);
                        //将上传的头像名称，关联到用户信息对象中
                        admin.setHeader(filename);
                    } catch (Exception e) {
//                        e.printStackTrace();
                    }
                }
            }
        }
        //   保存用户信息
        DataUtils.addAmin(admin);
        //  重定向
        resp.sendRedirect("login.jsp");
    }
}
